home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-15 | 73.3 KB | 2,127 lines | [TEXT/gamI] |
- ;==============================================================================
-
- ; file: "ptree1.scm"
-
- ;------------------------------------------------------------------------------
- ;
- ; Parse tree manipulation package: (part 1)
- ; -------------------------------
-
- ; This package contains procedures to construct the parse tree of a Scheme
- ; expression and manipulate the parse tree.
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Definition of the structures found in the parse tree.
-
- ; These structures define the nodes associated to expressions.
-
- ; information common to all nodes
-
- ; parent ; the node of which this node is a child
- ; children ; list of parse-trees of the sub-expressions
- ; fv ; set of free/non-global vars contained in this expr
- ; decl ; declarations that apply to this node
- ; source ; source corresponding to this node
-
- (define (node-parent x) (vector-ref x 1))
- (define (node-children x) (vector-ref x 2))
- (define (node-fv x) (vector-ref x 3))
- (define (node-decl x) (vector-ref x 4))
- (define (node-source x) (vector-ref x 5))
- (define (node-parent-set! x y) (vector-set! x 1 y))
- (define (node-fv-set! x y) (vector-set! x 3 y))
- (define (node-decl-set! x y) (vector-set! x 4 y))
- (define (node-source-set! x y) (vector-set! x 5 y))
-
- (define (node-children-set! x y)
- (vector-set! x 2 y)
- (for-each (lambda (child) (node-parent-set! child x)) y)
- (node-fv-invalidate! x))
-
- (define (node-fv-invalidate! x)
- (let loop ((node x))
- (if node
- (begin
- (node-fv-set! node #t)
- (loop (node-parent node))))))
-
- (define (make-cst ; node that represents constants
- parent children fv decl source ; common to all nodes
-
- val) ; value of the constant
-
- (vector cst-tag parent children fv decl source val))
-
- (define (cst? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) cst-tag)))
-
- (define (cst-val x) (vector-ref x 6))
- (define (cst-val-set! x y) (vector-set! x 6 y))
-
- (define cst-tag (list 'cst-tag))
-
- (define (make-ref ; node that represents variable references
- parent children fv decl source ; common to all nodes
-
- var) ; the variable which is referenced
-
- (vector ref-tag parent children fv decl source var))
-
- (define (ref? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) ref-tag)))
-
- (define (ref-var x) (vector-ref x 6))
- (define (ref-var-set! x y) (vector-set! x 6 y))
-
- (define ref-tag (list 'ref-tag))
-
- (define (make-set ; node that represents assignments (i.e. set! special forms)
- parent children fv decl source ; common to all nodes
-
- var) ; the variable which is assigned a value
-
- (vector set-tag parent children fv decl source var))
-
- (define (set? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) set-tag)))
-
- (define (set-var x) (vector-ref x 6))
- (define (set-var-set! x y) (vector-set! x 6 y))
-
- (define set-tag (list 'set-tag))
-
- (define (make-def ; node that represents toplevel definitions
- parent children fv decl source ; common to all nodes
-
- var) ; the global variable which is assigned a value
-
- (vector def-tag parent children fv decl source var))
-
- (define (def? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) def-tag)))
-
- (define (def-var x) (vector-ref x 6))
- (define (def-var-set! x y) (vector-set! x 6 y))
-
- (define def-tag (list 'def-tag))
-
- (define (make-tst ; node that represents conditionals (i.e. if special forms)
- parent children fv decl source ; common to all nodes
-
- )
-
- (vector tst-tag parent children fv decl source))
-
- (define (tst? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) tst-tag)))
-
- (define tst-tag (list 'tst-tag))
-
- (define (make-conj ; node that represents conjunctions (i.e. and special forms)
- parent children fv decl source ; common to all nodes
-
- )
-
- (vector conj-tag parent children fv decl source))
-
- (define (conj? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) conj-tag)))
-
- (define conj-tag (list 'conj-tag))
-
- (define (make-disj ; node that represents disjunctions (i.e. or special forms)
- parent children fv decl source ; common to all nodes
-
- )
-
- (vector disj-tag parent children fv decl source))
-
- (define (disj? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) disj-tag)))
-
- (define disj-tag (list 'disj-tag))
-
- (define (make-prc ; node that represents procedures (i.e. lambda-expressions)
- parent children fv decl source ; common to all nodes
-
- name ; name of this procedure (string)
- min ; number of required parameters
- rest ; #t if the last parameter is a rest parameter
- parms) ; the list of parameter variables in order
-
- (vector prc-tag parent children fv decl source name min rest parms))
-
- (define (prc? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) prc-tag)))
-
- (define (prc-name x) (vector-ref x 6))
- (define (prc-min x) (vector-ref x 7))
- (define (prc-rest x) (vector-ref x 8))
- (define (prc-parms x) (vector-ref x 9))
- (define (prc-name-set! x y) (vector-set! x 6 y))
- (define (prc-min-set! x y) (vector-set! x 7 y))
- (define (prc-rest-set! x y) (vector-set! x 8 y))
- (define (prc-parms-set! x y) (vector-set! x 9 y))
-
- (define prc-tag (list 'prc-tag))
-
- (define (make-app ; node that represents procedure calls
- parent children fv decl source ; common to all nodes
-
- )
-
- (vector app-tag parent children fv decl source))
-
- (define (app? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) app-tag)))
-
- (define app-tag (list 'app-tag))
-
- (define (make-fut ; node that represents future constructs
- parent children fv decl source ; common to all nodes
-
- )
-
- (vector fut-tag parent children fv decl source))
-
- (define (fut? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) fut-tag)))
-
- (define fut-tag (list 'fut-tag))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Procedures to create parse tree nodes and extract sub-nodes.
-
- (define (new-cst source decl val)
- (make-cst #f '() #t decl source val))
-
- (define (new-ref source decl var)
- (let ((node (make-ref #f '() #t decl source var)))
- (var-refs-set! var (set-adjoin (var-refs var) node))
- node))
-
- (define (new-ref-extended-bindings source name env)
- (new-ref source
- (add-extended-bindings (env-declarations env))
- (env-lookup-global-var env name)))
-
- (define (new-set source decl var val)
- (let ((node (make-set #f (list val) #t decl source var)))
- (var-sets-set! var (set-adjoin (var-sets var) node))
- (node-parent-set! val node)
- node))
-
- (define (set-val x)
- (if (set? x)
- (car (node-children x))
- (compiler-internal-error "set-val, 'set' node expected" x)))
-
- (define (new-def source decl var val)
- (let ((node (make-def #f (list val) #t decl source var)))
- (var-sets-set! var (set-adjoin (var-sets var) node))
- (node-parent-set! val node)
- node))
-
- (define (def-val x)
- (if (def? x)
- (car (node-children x))
- (compiler-internal-error "def-val, 'def' node expected" x)))
-
- (define (new-tst source decl pre con alt)
- (let ((node (make-tst #f (list pre con alt) #t decl source)))
- (node-parent-set! pre node)
- (node-parent-set! con node)
- (node-parent-set! alt node)
- node))
-
- (define (tst-pre x)
- (if (tst? x)
- (car (node-children x))
- (compiler-internal-error "tst-pre, 'tst' node expected" x)))
-
- (define (tst-con x)
- (if (tst? x)
- (cadr (node-children x))
- (compiler-internal-error "tst-con, 'tst' node expected" x)))
-
- (define (tst-alt x)
- (if (tst? x)
- (caddr (node-children x))
- (compiler-internal-error "tst-alt, 'tst' node expected" x)))
-
- (define (new-conj source decl pre alt)
- (let ((node (make-conj #f (list pre alt) #t decl source)))
- (node-parent-set! pre node)
- (node-parent-set! alt node)
- node))
-
- (define (conj-pre x)
- (if (conj? x)
- (car (node-children x))
- (compiler-internal-error "conj-pre, 'conj' node expected" x)))
-
- (define (conj-alt x)
- (if (conj? x)
- (cadr (node-children x))
- (compiler-internal-error "conj-alt, 'conj' node expected" x)))
-
- (define (new-disj source decl pre alt)
- (let ((node (make-disj #f (list pre alt) #t decl source)))
- (node-parent-set! pre node)
- (node-parent-set! alt node)
- node))
-
- (define (disj-pre x)
- (if (disj? x)
- (car (node-children x))
- (compiler-internal-error "disj-pre, 'disj' node expected" x)))
-
- (define (disj-alt x)
- (if (disj? x)
- (cadr (node-children x))
- (compiler-internal-error "disj-alt, 'disj' node expected" x)))
-
- (define (new-prc source decl name min rest parms body)
- (let ((node (make-prc #f (list body) #t decl source name min rest parms)))
- (for-each (lambda (x) (var-bound-set! x node)) parms)
- (node-parent-set! body node)
- node))
-
- (define (prc-body x)
- (if (prc? x)
- (car (node-children x))
- (compiler-internal-error "prc-body, 'proc' node expected" x)))
-
- (define (new-call source decl oper args)
- (let ((node (make-app #f (cons oper args) #t decl source)))
- (node-parent-set! oper node)
- (for-each (lambda (x) (node-parent-set! x node)) args)
- node))
-
- (define (new-call* source decl oper args)
- (if *ptree-port*
- (if (ref? oper)
- (let ((var (ref-var oper)))
- (if (global? var)
- (let ((proc (standard-procedure (var-name var) (node-decl oper))))
- (if (and proc
- (not (nb-args-conforms?
- (length args)
- (standard-procedure-call-pattern proc))))
- (begin
- (display "*** Warning: \"" *ptree-port*)
- (display (var-name var) *ptree-port*)
- (display "\" is called with " *ptree-port*)
- (display (length args) *ptree-port*)
- (display " argument(s)." *ptree-port*)
- (newline *ptree-port*))))))))
- (new-call source decl oper args))
-
- (define (app-oper x)
- (if (app? x)
- (car (node-children x))
- (compiler-internal-error "app-oper, 'call' node expected" x)))
-
- (define (app-args x)
- (if (app? x)
- (cdr (node-children x))
- (compiler-internal-error "app-args, 'call' node expected" x)))
-
- (define (oper-pos? node)
- (let ((parent (node-parent node)))
- (if parent
- (and (app? parent)
- (eq? (app-oper parent) node))
- #f)))
-
- (define (new-fut source decl val)
- (let ((node (make-fut #f (list val) #t decl source)))
- (node-parent-set! val node)
- node))
-
- (define (fut-val x)
- (if (fut? x)
- (car (node-children x))
- (compiler-internal-error "fut-val, 'fut' node expected" x)))
-
- (define (new-disj-call source decl pre oper alt)
- (new-call* source decl
- (let* ((parms (new-temps source '(temp)))
- (temp (car parms)))
- (new-prc source decl #f 1 #f parms
- (new-tst source decl
- (new-ref source decl temp)
- (new-call* source decl oper (list (new-ref source decl temp)))
- alt)))
- (list pre)))
-
- (define (new-seq source decl before after)
- (new-call* source decl
- (new-prc source decl #f 1 #f (new-temps source '(temp))
- after)
- (list before)))
-
- (define (new-let ptree proc vars vals body)
- (if (pair? vars)
- (new-call (node-source ptree) (node-decl ptree)
- (new-prc (node-source proc) (node-decl proc)
- (prc-name proc)
- (length vars)
- #f
- (reverse vars)
- body)
- (reverse vals))
- body))
-
- (define (new-temps source names)
- (if (null? names)
- '()
- (cons (make-var (car names) #t (set-empty) (set-empty) source)
- (new-temps source (cdr names)))))
-
- (define (new-variables vars)
- (if (null? vars)
- '()
- (cons (make-var (source-code (car vars)) #t (set-empty) (set-empty) (car vars))
- (new-variables (cdr vars)))))
-
- (define (set-prc-names! vars vals)
- (let loop ((vars vars) (vals vals))
- (if (not (null? vars))
- (let ((var (car vars))
- (val (car vals)))
- (if (prc? val)
- (prc-name-set! val (symbol->string (var-name var))))
- (loop (cdr vars) (cdr vals))))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Procedures to get variable classes from nodes.
-
- (define (free-variables node) ; set of free variables used in the expression
- (if (eq? (node-fv node) #t)
- (let ((x (apply set-union (map free-variables (node-children node)))))
- (node-fv-set! node
- (cond ((ref? node)
- (if (global? (ref-var node)) x (set-adjoin x (ref-var node))))
- ((set? node)
- (if (global? (set-var node)) x (set-adjoin x (set-var node))))
- ((prc? node)
- (set-difference x (list->set (prc-parms node))))
- ((and (app? node) (prc? (app-oper node)))
- (set-difference x (list->set (prc-parms (app-oper node)))))
- (else
- x)))))
- (node-fv node))
-
- (define (bound-variables node) ; set of variables bound by a procedure
- (list->set (prc-parms node)))
-
- (define (not-mutable? var)
- (set-empty? (var-sets var)))
-
- (define (mutable? var)
- (not (not-mutable? var)))
-
- (define (bound? var)
- (var-bound var))
-
- (define (global? var)
- (not (bound? var)))
-
- (define (global-val var) ; get value of a global if it is known to be constant
- (and (global? var)
- (let ((sets (set->list (var-sets var))))
- (and (pair? sets) (null? (cdr sets))
- (def? (car sets))
- (eq? (compilation-strategy (node-decl (car sets))) BLOCK-sym)
- (def-val (car sets))))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Canonical symbols for procedures needed by the front end:
-
- (define **NOT-sym (string->canonical-symbol "##NOT"))
- (define **QUASI-APPEND-sym (string->canonical-symbol "##QUASI-APPEND"))
- (define **QUASI-LIST-sym (string->canonical-symbol "##QUASI-LIST"))
- (define **QUASI-CONS-sym (string->canonical-symbol "##QUASI-CONS"))
- (define **QUASI-LIST->VECTOR-sym (string->canonical-symbol "##QUASI-LIST->VECTOR"))
- (define **CASE-MEMV-sym (string->canonical-symbol "##CASE-MEMV"))
- (define **UNASSIGNED?-sym (string->canonical-symbol "##UNASSIGNED?"))
- (define **MAKE-CELL-sym (string->canonical-symbol "##MAKE-CELL"))
- (define **CELL-REF-sym (string->canonical-symbol "##CELL-REF"))
- (define **CELL-SET!-sym (string->canonical-symbol "##CELL-SET!"))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Declarations relevant to parsing:
-
- ; Dialect related declarations:
- ;
- ; (ieee-scheme) use IEEE Scheme
- ; (r4rs-scheme) use R4RS Scheme
- ; (multilisp) use Multilisp
- ;
- ; Lambda-lifting declarations:
- ;
- ; (lambda-lift) can lambda-lift procedures
- ; (not lambda-lift) can't lambda-lift procedures
- ;
- ; Compilation strategy declarations:
- ;
- ; (block) global vars defined are only mutated by code in the current file
- ; (separate) global vars defined can be mutated by other code
- ;
- ; Global variable binding declarations:
- ;
- ; (standard-bindings) compiler can assume standard bindings
- ; (standard-bindings <var1> ...) assume st. bind. for vars specified
- ; (not standard-bindings) can't assume st. bind. for any var
- ; (not standard-bindings <var1> ...) can't assume st. bind. for vars spec.
- ;
- ; (extended-bindings) compiler can assume extended bindings
- ; (extended-bindings <var1> ...) assume ext. bind. for vars specified
- ; (not extended-bindings) can't assume ext. bind. for any var
- ; (not extended-bindings <var1> ...) can't assume ext. bind. for vars spec.
- ;
- ; Code safety declarations:
- ;
- ; (safe) runtime errors won't crash system
- ; (not safe) assume program doesn't contain errors
- ;
- ; Interrupt checking declarations:
- ;
- ; (intr-checks) generate interrupt checks
- ; (not intr-checks) don't generate interrupt checks
- ;
- ; Future implementation method declarations:
- ;
- ; (futures off) future = identity operation
- ; (futures delay) 'delay' future method
- ; (futures eager) 'eager' future method
- ; (futures lazy) 'lazy' future method
- ; (futures eager-inline) inlined 'eager' future method
- ;
- ; Touching analysis declarations:
- ;
- ; (autotouch) compiler does touching wherever needed
- ; (not autotouch) (touch ...) are explicit
-
- (define IEEE-SCHEME-sym (string->canonical-symbol "IEEE-SCHEME"))
- (define R4RS-SCHEME-sym (string->canonical-symbol "R4RS-SCHEME"))
- (define MULTILISP-sym (string->canonical-symbol "MULTILISP"))
-
- (define LAMBDA-LIFT-sym (string->canonical-symbol "LAMBDA-LIFT"))
-
- (define BLOCK-sym (string->canonical-symbol "BLOCK"))
- (define SEPARATE-sym (string->canonical-symbol "SEPARATE"))
-
- (define STANDARD-BINDINGS-sym (string->canonical-symbol "STANDARD-BINDINGS"))
- (define EXTENDED-BINDINGS-sym (string->canonical-symbol "EXTENDED-BINDINGS"))
-
- (define SAFE-sym (string->canonical-symbol "SAFE"))
-
- (define INTR-CHECKS-sym (string->canonical-symbol "INTR-CHECKS"))
-
- (define FUTURES-sym (string->canonical-symbol "FUTURES"))
- (define OFF-sym (string->canonical-symbol "OFF"))
- (define LAZY-sym (string->canonical-symbol "LAZY"))
- (define EAGER-sym (string->canonical-symbol "EAGER"))
- (define EAGER-INLINE-sym (string->canonical-symbol "EAGER-INLINE"))
-
- (define AUTOTOUCH-sym (string->canonical-symbol "AUTOTOUCH"))
-
- (define-flag-decl IEEE-SCHEME-sym 'dialect)
- (define-flag-decl R4RS-SCHEME-sym 'dialect)
- (define-flag-decl MULTILISP-sym 'dialect)
-
- (define-boolean-decl LAMBDA-LIFT-sym)
-
- (define-flag-decl BLOCK-sym 'compilation-strategy)
- (define-flag-decl SEPARATE-sym 'compilation-strategy)
-
- (define-namable-boolean-decl STANDARD-BINDINGS-sym)
- (define-namable-boolean-decl EXTENDED-BINDINGS-sym)
-
- (define-boolean-decl SAFE-sym)
-
- (define-boolean-decl INTR-CHECKS-sym)
-
- (define-parameterized-decl FUTURES-sym)
-
- (define-boolean-decl AUTOTOUCH-sym)
-
- (define (scheme-dialect decl) ; returns dialect in effect
- (declaration-value 'dialect #f IEEE-SCHEME-sym decl))
-
- (define (lambda-lift? decl) ; true iff should lambda-lift
- (declaration-value LAMBDA-LIFT-sym #f #t decl))
-
- (define (compilation-strategy decl) ; returns compilation strategy in effect
- (declaration-value 'compilation-strategy #f SEPARATE-sym decl))
-
- (define (standard-binding? name decl) ; true iff name's binding is standard
- (declaration-value STANDARD-BINDINGS-sym name #f decl))
-
- (define (extended-binding? name decl) ; true iff name's binding is extended
- (declaration-value EXTENDED-BINDINGS-sym name #f decl))
-
- (define (add-extended-bindings decl)
- (add-decl (list EXTENDED-BINDINGS-sym #t) decl))
-
- (define (intr-checks? decl) ; true iff system should generate interrupt checks
- (declaration-value INTR-CHECKS-sym #f #t decl))
-
- (define (futures-method decl) ; returns type of future implementation method
- (declaration-value FUTURES-sym #f LAZY-sym decl))
-
- (define (add-delay decl)
- (add-decl (list FUTURES-sym DELAY-sym) decl))
-
- (define (autotouch? decl) ; true iff autotouching (default depends on dialect)
- (declaration-value AUTOTOUCH-sym
- #f
- (eq? (scheme-dialect decl) MULTILISP-sym)
- decl))
-
- (define (safe? decl) ; true iff system should prevent fatal runtime errors
- (declaration-value SAFE-sym #f #f decl))
-
- (define (add-not-safe decl)
- (add-decl (list SAFE-sym #f) decl))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Dialect info:
-
- (define (dialect-specific-keywords dialect)
- (cond ((eq? dialect IEEE-SCHEME-sym)
- ieee-scheme-specific-keywords)
- ((eq? dialect R4RS-SCHEME-sym)
- r4rs-scheme-specific-keywords)
- ((eq? dialect MULTILISP-sym)
- multilisp-specific-keywords)
- (else
- (compiler-internal-error
- "dialect-specific-keywords, unknown dialect" dialect))))
-
- (define (dialect-specific-procedures dialect)
- (cond ((eq? dialect IEEE-SCHEME-sym)
- ieee-scheme-specific-procedures)
- ((eq? dialect R4RS-SCHEME-sym)
- r4rs-scheme-specific-procedures)
- ((eq? dialect MULTILISP-sym)
- multilisp-specific-procedures)
- (else
- (compiler-internal-error
- "dialect-specific-procedures, unknown dialect" dialect))))
-
- (define (make-standard-procedure x)
- (cons (string->canonical-symbol (car x)) (cdr x)))
-
- (define (standard-procedure name decl)
- (or (assq name (dialect-specific-procedures (scheme-dialect decl)))
- (assq name common-procedures)))
-
- (define (standard-procedure-call-pattern proc)
- (cdr proc))
-
- ; IEEE Scheme
-
- (define ieee-scheme-specific-keywords
- '())
-
- (define ieee-scheme-specific-procedures (map make-standard-procedure '(
-
- )))
-
- ; R4RS Scheme
-
- (define r4rs-scheme-specific-keywords
- (list DELAY-sym))
-
- (define r4rs-scheme-specific-procedures (map make-standard-procedure '(
-
- ; section 6.3
-
- ("LIST-TAIL" 2)
-
- ; section 6.5
-
- ("-" . 1) ("/" . 1)
-
- ; section 6.7
-
- ("STRING->LIST" 1) ("LIST->STRING" 1) ("STRING-COPY" 1) ("STRING-FILL!" 2)
-
- ; section 6.8
-
- ("VECTOR->LIST" 1) ("LIST->VECTOR" 1) ("VECTOR-FILL!" 2)
-
- ; section 6.9
-
- ("FORCE" 1)
-
- ; section 6.10
-
- ("WITH-INPUT-FROM-FILE" 2) ("WITH-OUTPUT-TO-FILE" 2) ("CHAR-READY?" 0 1)
- ("LOAD" 1) ("TRANSCRIPT-ON" 1) ("TRANSCRIPT-OFF" 0)
-
- )))
-
- ; Multilisp
-
- (define multilisp-specific-keywords
- (list DELAY-sym FUTURE-sym))
-
- (define multilisp-specific-procedures (map make-standard-procedure '(
-
- ("FORCE" 1)
- ("TOUCH" 1)
-
- )))
-
- ; common stuff
-
- (define common-keywords
- (list QUOTE-sym QUASIQUOTE-sym UNQUOTE-sym UNQUOTE-SPLICING-sym
- LAMBDA-sym IF-sym SET!-sym COND-sym =>-sym ELSE-sym AND-sym OR-sym
- CASE-sym LET-sym LET*-sym LETREC-sym BEGIN-sym DO-sym DEFINE-sym
- **DEFINE-MACRO-sym **DECLARE-sym **INCLUDE-sym))
-
- (define common-procedures (map make-standard-procedure '(
-
- ; taken from IEEE Scheme standard draft P1178/D4
-
- ; section 6.1
-
- ("NOT" 1) ("BOOLEAN?" 1)
-
- ; section 6.2
-
- ("EQV?" 2) ("EQ?" 2) ("EQUAL?" 2)
-
- ; section 6.3
-
- ("PAIR?" 1) ("CONS" 2) ("CAR" 1) ("CDR" 1) ("SET-CAR!" 2) ("SET-CDR!" 2)
- ("CAAR" 1) ("CADR" 1) ("CDAR" 1) ("CDDR" 1) ("CAAAR" 1) ("CAADR" 1)
- ("CADAR" 1) ("CADDR" 1) ("CDAAR" 1) ("CDADR" 1) ("CDDAR" 1) ("CDDDR" 1)
- ("CAAAAR" 1) ("CAAADR" 1) ("CAADAR" 1) ("CAADDR" 1) ("CADAAR" 1)
- ("CADADR" 1) ("CADDAR" 1) ("CADDDR" 1) ("CDAAAR" 1) ("CDAADR" 1)
- ("CDADAR" 1) ("CDADDR" 1) ("CDDAAR" 1) ("CDDADR" 1) ("CDDDAR" 1)
- ("CDDDDR" 1) ("NULL?" 1) ("LIST?" 1) ("LIST" . 0) ("LENGTH" 1)
- ("APPEND" . 0) ("REVERSE" 1) ("LIST-REF" 2) ("MEMQ" 2) ("MEMV" 2)
- ("MEMBER" 2) ("ASSQ" 2) ("ASSV" 2) ("ASSOC" 2)
-
- ; section 6.4
-
- ("SYMBOL?" 1) ("SYMBOL->STRING" 1) ("STRING->SYMBOL" 1)
-
- ; section 6.5
-
- ("NUMBER?" 1) ("COMPLEX?" 1) ("REAL?" 1) ("RATIONAL?" 1) ("INTEGER?" 1)
- ("EXACT?" 1) ("INEXACT?" 1) ("=" . 2) ("<" . 2) (">" . 2) ("<=" . 2)
- (">=" . 2) ("ZERO?" 1) ("POSITIVE?" 1) ("NEGATIVE?" 1) ("ODD?" 1) ("EVEN?" 1)
- ("MAX" . 1) ("MIN" . 1) ("+" . 0) ("*" . 0) ("-" 1 2) ("/" 1 2) ("ABS" 1)
- ("QUOTIENT" 2) ("REMAINDER" 2) ("MODULO" 2) ("GCD" . 0) ("LCM" . 0)
- ("NUMERATOR" 1) ("DENOMINATOR" 1) ("FLOOR" 1) ("CEILING" 1)
- ("TRUNCATE" 1) ("ROUND" 1) ("RATIONALIZE" 2) ("EXP" 1) ("LOG" 1)
- ("SIN" 1) ("COS" 1) ("TAN" 1) ("ASIN" 1) ("ACOS" 1) ("ATAN" 1 2) ("SQRT" 1)
- ("EXPT" 2) ("MAKE-RECTANGULAR" 2) ("MAKE-POLAR" 2) ("REAL-PART" 1)
- ("IMAG-PART" 1) ("MAGNITUDE" 1) ("ANGLE" 1) ("EXACT->INEXACT" 1)
- ("INEXACT->EXACT" 1) ("NUMBER->STRING" 1 2) ("STRING->NUMBER" 1 2)
-
- ; section 6.6
-
- ("CHAR?" 1) ("CHAR=?" 2) ("CHAR<?" 2) ("CHAR>?" 2) ("CHAR<=?" 2)
- ("CHAR>=?" 2) ("CHAR-CI=?" 2) ("CHAR-CI<?" 2) ("CHAR-CI>?" 2)
- ("CHAR-CI<=?" 2) ("CHAR-CI>=?" 2) ("CHAR-ALPHABETIC?" 1)
- ("CHAR-NUMERIC?" 1) ("CHAR-WHITESPACE?" 1) ("CHAR-UPPER-CASE?" 1)
- ("CHAR-LOWER-CASE?" 1) ("CHAR->INTEGER" 1) ("INTEGER->CHAR" 1)
- ("CHAR-UPCASE" 1) ("CHAR-DOWNCASE" 1)
-
- ; section 6.7
-
- ("STRING?" 1) ("MAKE-STRING" 1 2) ("STRING" . 0) ("STRING-LENGTH" 1)
- ("STRING-REF" 2) ("STRING-SET!" 3) ("STRING=?" 2) ("STRING<?" 2)
- ("STRING>?" 2) ("STRING<=?" 2) ("STRING>=?" 2) ("STRING-CI=?" 2)
- ("STRING-CI<?" 2) ("STRING-CI>?" 2) ("STRING-CI<=?" 2) ("STRING-CI>=?" 2)
- ("SUBSTRING" 3) ("STRING-APPEND" . 0)
-
- ; section 6.8
-
- ("VECTOR?" 1) ("MAKE-VECTOR" 1 2) ("VECTOR" . 0) ("VECTOR-LENGTH" 1)
- ("VECTOR-REF" 2) ("VECTOR-SET!" 3)
-
- ; section 6.9
-
- ("PROCEDURE?" 1) ("APPLY" . 2) ("MAP" . 2) ("FOR-EACH" . 2)
- ("CALL-WITH-CURRENT-CONTINUATION" 1)
-
- ; section 6.10
-
- ("CALL-WITH-INPUT-FILE" 2) ("CALL-WITH-OUTPUT-FILE" 2) ("INPUT-PORT?" 1)
- ("OUTPUT-PORT?" 1) ("CURRENT-INPUT-PORT" 0) ("CURRENT-OUTPUT-PORT" 0)
- ("OPEN-INPUT-FILE" 1) ("OPEN-OUTPUT-FILE" 1) ("CLOSE-INPUT-PORT" 1)
- ("CLOSE-OUTPUT-PORT" 1) ("EOF-OBJECT?" 1) ("READ" 0 1) ("READ-CHAR" 0 1)
- ("PEEK-CHAR" 0 1) ("WRITE" 1 2) ("DISPLAY" 1 2) ("NEWLINE" 0 1)
- ("WRITE-CHAR" 1 2)
-
- )))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; (parse-program program env proc) returns a list of parse trees/environment
- ; pairs describing the program and the final global environment.
-
- (define (parse-program program env proc)
-
- (if *ptree-port*
- (begin
- (display "Parsing:" *ptree-port*)
- (newline *ptree-port*)))
-
- (parse-prog program env '()
- (lambda (lst env)
-
- (if *ptree-port*
- (newline *ptree-port*))
-
- (proc lst env))))
-
- (define (parse-prog program env lst proc)
- (if (null? program)
- (proc (reverse lst) env)
- (let ((source (car program)))
-
- (cond ((macro-expr? source env)
- (parse-prog
- (cons (macro-expand source env) (cdr program))
- env
- lst
- proc))
-
- ((begin-defs-expr? source)
- (parse-prog
- (append (begin-defs-body source) (cdr program))
- env
- lst
- proc))
-
- ((include-expr? source)
-
- (if *ptree-port*
- (display " " *ptree-port*))
-
- (let ((x (file->sources* (include-filename source)
- *ptree-port*
- (source-locat source))))
-
- (if *ptree-port*
- (newline *ptree-port*))
-
- (parse-prog
- (append x (cdr program))
- env
- lst
- proc)))
-
- ((define-macro-expr? source env)
-
- (if *ptree-port*
- (begin
- (display " \"macro\"" *ptree-port*)
- (newline *ptree-port*)))
-
- (parse-prog
- (cdr program)
- (add-macro source env)
- lst
- proc))
-
- ((declare-expr? source)
-
- (if *ptree-port*
- (begin
- (display " \"decl\"" *ptree-port*)
- (newline *ptree-port*)))
-
- (parse-prog
- (cdr program)
- (add-declarations source env)
- lst
- proc))
-
- ((define-expr? source env)
- (let* ((var** (definition-variable source))
- (var* (source-code var**))
- (var (env-lookup-var env var* var**)))
-
- (if *ptree-port*
- (begin
- (display " " *ptree-port*)
- (display (var-name var) *ptree-port*)
- (newline *ptree-port*)))
-
- (let ((node (pt (definition-value source) env 'TRUE)))
- (set-prc-names! (list var) (list node))
- (parse-prog
- (cdr program)
- env
- (cons (cons (new-def source (env-declarations env) var node) env) lst)
- proc))))
-
- (else
-
- (if *ptree-port*
- (begin
- (display " \"expr\"" *ptree-port*)
- (newline *ptree-port*)))
-
- (parse-prog
- (cdr program)
- env
- (cons (cons (pt source env 'TRUE) env) lst)
- proc))))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; (pt source env use) returns the parse tree for the Scheme source expression
- ; 'source' in the environment 'env'. If 'source' is not syntactically
- ; correct, an error is signaled. The value of 'use' determines what the
- ; expression's value will be used for; it must be one of the following:
- ;
- ; TRUE : the true value of the expression is needed
- ; PRED : the value is used as a predicate
- ; NONE : the value is not needed (but its side effect might)
-
- (define (pt-syntax-error source msg . args)
- (apply compiler-user-error
- (cons (source-locat source)
- (cons (string-append "Syntax error -- " msg)
- args))))
-
- (define (pt source env use)
- (cond ((macro-expr? source env) (pt (macro-expand source env) env use))
- ((self-eval-expr? source) (pt-self-eval source env use))
- ((quote-expr? source) (pt-quote source env use))
- ((quasiquote-expr? source) (pt-quasiquote source env use))
- ((unquote-expr? source)
- (pt-syntax-error source "Ill-placed 'unquote'"))
- ((unquote-splicing-expr? source)
- (pt-syntax-error source "Ill-placed 'unquote-splicing'"))
- ((var-expr? source env) (pt-var source env use))
- ((set!-expr? source env) (pt-set! source env use))
- ((lambda-expr? source env) (pt-lambda source env use))
- ((if-expr? source) (pt-if source env use))
- ((cond-expr? source) (pt-cond source env use))
- ((and-expr? source) (pt-and source env use))
- ((or-expr? source) (pt-or source env use))
- ((case-expr? source) (pt-case source env use))
- ((let-expr? source env) (pt-let source env use))
- ((let*-expr? source env) (pt-let* source env use))
- ((letrec-expr? source env) (pt-letrec source env use))
- ((begin-expr? source) (pt-begin source env use))
- ((do-expr? source env) (pt-do source env use))
- ((define-expr? source env)
- (pt-syntax-error source "Ill-placed 'define'"))
- ((delay-expr? source env) (pt-delay source env use))
- ((future-expr? source env) (pt-future source env use))
- ((define-macro-expr? source env)
- (pt-syntax-error source "Ill-placed '##define-macro'"))
- ((begin-defs-expr? source)
- (pt-syntax-error source "Ill-placed 'begin' style definitions"))
- ((declare-expr? source)
- (pt-syntax-error source "Ill-placed '##declare'"))
- ((combination-expr? source) (pt-combination source env use))
- (else
- (compiler-internal-error "pt, unknown expression type" source))))
-
- (define (macro-expand source env)
- (let ((code (source-code source)))
- (expression->source
- (apply (cdr (env-lookup-macro env (source-code (car code))))
- (cdr (source->expression source)))
- source)))
-
- (define (pt-self-eval source env use)
- (let ((val (source->expression source)))
- (if (eq? use 'NONE)
- (new-cst source (env-declarations env) undef-object)
- (new-cst source (env-declarations env) val))))
-
- (define (pt-quote source env use)
- (let ((code (source-code source)))
- (if (eq? use 'NONE)
- (new-cst source (env-declarations env) undef-object)
- (new-cst source (env-declarations env) (source->expression (cadr code))))))
-
- (define (pt-quasiquote source env use)
- (let ((code (source-code source)))
- (pt-quasiquotation (cadr code) 1 env)))
-
- (define (pt-quasiquotation form level env)
- (cond ((= level 0)
- (pt form env 'TRUE))
- ((quasiquote-expr? form)
- (pt-quasiquotation-list form (source-code form) (+ level 1) env))
- ((unquote-expr? form)
- (if (= level 1)
- (pt (cadr (source-code form)) env 'TRUE)
- (pt-quasiquotation-list form (source-code form) (- level 1) env)))
- ((unquote-splicing-expr? form)
- (if (= level 1)
- (pt-syntax-error form "Ill-placed 'unquote-splicing'")
- (pt-quasiquotation-list form (source-code form) (- level 1) env)))
- ((pair? (source-code form))
- (pt-quasiquotation-list form (source-code form) level env))
- ((vector? (source-code form))
- (vector-form
- form
- (pt-quasiquotation-list form (vector->lst (source-code form)) level env)
- env))
- (else
- (new-cst form (env-declarations env) (source->expression form)))))
-
- (define (pt-quasiquotation-list form l level env)
- (cond ((pair? l)
- (if (and (unquote-splicing-expr? (car l)) (= level 1))
- (let ((x (pt (cadr (source-code (car l))) env 'TRUE)))
- (if (null? (cdr l))
- x
- (append-form (car l) x (pt-quasiquotation-list form (cdr l) 1 env) env)))
- (cons-form form
- (pt-quasiquotation (car l) level env)
- (pt-quasiquotation-list form (cdr l) level env)
- env)))
- ((null? l)
- (new-cst form (env-declarations env) '()))
- (else
- (pt-quasiquotation l level env))))
-
- (define (append-form source ptree1 ptree2 env)
- (cond ((and (cst? ptree1) (cst? ptree2))
- (new-cst source (env-declarations env)
- (append (cst-val ptree1) (cst-val ptree2))))
- ((and (cst? ptree2) (null? (cst-val ptree2)))
- ptree1)
- (else
- (new-call* source (add-not-safe (env-declarations env))
- (new-ref-extended-bindings source **QUASI-APPEND-sym env)
- (list ptree1 ptree2)))))
-
- (define (cons-form source ptree1 ptree2 env)
- (cond ((and (cst? ptree1) (cst? ptree2))
- (new-cst source (env-declarations env)
- (cons (cst-val ptree1) (cst-val ptree2))))
- ((and (cst? ptree2) (null? (cst-val ptree2)))
- (new-call* source (add-not-safe (env-declarations env))
- (new-ref-extended-bindings source **QUASI-LIST-sym env)
- (list ptree1)))
- (else
- (new-call* source (add-not-safe (env-declarations env))
- (new-ref-extended-bindings source **QUASI-CONS-sym env)
- (list ptree1 ptree2)))))
-
- (define (vector-form source ptree env)
- (if (cst? ptree)
- (new-cst source (env-declarations env)
- (lst->vector (cst-val ptree)))
- (new-call* source (add-not-safe (env-declarations env))
- (new-ref-extended-bindings source **QUASI-LIST->VECTOR-sym env)
- (list ptree))))
-
- (define (pt-var source env use)
- (if (eq? use 'NONE)
- (new-cst source (env-declarations env) undef-object)
- (new-ref source (env-declarations env)
- (env-lookup-var env (source-code source) source))))
-
- (define (pt-set! source env use)
- (let ((code (source-code source)))
- (new-set source (env-declarations env)
- (env-lookup-var env (source-code (cadr code)) (cadr code))
- (pt (caddr code) env 'TRUE))))
-
- (define (pt-lambda source env use)
- (let ((code (source-code source)))
-
- (define (new-params parms)
- (cond ((pair? parms)
- (let* ((parm* (car parms))
- (parm (source-code parm*))
- (p* (if (pair? parm) (car parm) parm*)))
- (cons (make-var (source-code p*) #t (set-empty) (set-empty) p*)
- (new-params (cdr parms)))))
- ((null? parms)
- '())
- (else
- (list (make-var (source-code parms) #t (set-empty) (set-empty) parms)))))
-
- (define (min-params parms)
- (let loop ((l parms) (n 0))
- (if (pair? l)
- (if (pair? (source-code (car l)))
- n
- (loop (cdr l) (+ n 1)))
- n)))
-
- (define (rest-param? parms)
- (if (pair? parms)
- (rest-param? (cdr parms))
- (not (null? parms))))
-
- (define (optionals parms source body env)
- (if (pair? parms)
- (let* ((parm* (car parms))
- (parm (source-code parm*)))
- (if (and (pair? parm) (length? parm 2))
- (let* ((var (car parm))
- (vars (new-variables (list var)))
- (decl (env-declarations env)))
- (new-call* parm* decl
- (new-prc parm* decl
- #f
- 1
- #f
- vars
- (optionals (cdr parms) source body (env-frame env vars)))
- (list (new-tst parm* decl
- (new-call* parm* decl
- (new-ref-extended-bindings parm* **UNASSIGNED?-sym env)
- (list (new-ref parm* decl
- (env-lookup-var env (source-code var) var))))
- (pt (cadr parm) env 'TRUE)
- (new-ref parm* decl
- (env-lookup-var env (source-code var) var))))))
- (optionals (cdr parms) source body env)))
- (pt-body source body env 'TRUE)))
-
- (if (eq? use 'NONE)
- (new-cst source (env-declarations env) undef-object)
- (let* ((parms (source->parms (cadr code)))
- (frame (new-params parms)))
- (new-prc source (env-declarations env)
- #f
- (min-params parms)
- (rest-param? parms)
- frame
- (optionals parms
- source
- (cddr code)
- (env-frame env frame)))))))
-
- (define (source->parms source)
- (let ((x (source-code source)))
- (if (or (pair? x) (null? x)) x source)))
-
- (define (pt-body source body env use)
-
- (define (letrec-defines vars vals envs body env)
- (cond ((null? body)
- (pt-syntax-error
- source
- "Body must contain at least one evaluable expression"))
- ((macro-expr? (car body) env)
- (letrec-defines vars
- vals
- envs
- (cons (macro-expand (car body) env)
- (cdr body))
- env))
- ((begin-defs-expr? (car body))
- (letrec-defines vars
- vals
- envs
- (append (begin-defs-body (car body))
- (cdr body))
- env))
- ((include-expr? (car body))
- (if *ptree-port*
- (display " " *ptree-port*))
- (let ((x (file->sources* (include-filename (car body))
- *ptree-port*
- (source-locat (car body)))))
- (if *ptree-port*
- (newline *ptree-port*))
- (letrec-defines vars
- vals
- envs
- (append x (cdr body))
- env)))
- ((define-expr? (car body) env)
- (let* ((var** (definition-variable (car body)))
- (var* (source-code var**))
- (var (env-define-var env var* var**)))
- (letrec-defines (cons var vars)
- (cons (definition-value (car body)) vals)
- (cons env envs)
- (cdr body)
- env)))
- ((declare-expr? (car body))
- (letrec-defines vars
- vals
- envs
- (cdr body)
- (add-declarations (car body) env)))
- ((define-macro-expr? (car body) env)
- (letrec-defines vars
- vals
- envs
- (cdr body)
- (add-macro (car body) env)))
- ((null? vars)
- (pt-sequence source body env use))
- (else
- (let ((vars* (reverse vars)))
- (let loop ((vals* '()) (l1 vals) (l2 envs))
- (if (not (null? l1))
- (loop (cons (pt (car l1) (car l2) 'TRUE) vals*)
- (cdr l1)
- (cdr l2))
- (pt-recursive-let source vars* vals* body env use)))))))
-
- (letrec-defines '() '() '() body (env-frame env '())))
-
- (define (pt-sequence source seq env use)
- (if (length? seq 1)
- (pt (car seq) env use)
- (new-seq source (env-declarations env)
- (pt (car seq) env 'NONE)
- (pt-sequence source (cdr seq) env use))))
-
- (define (pt-if source env use)
- (let ((code (source-code source)))
- (new-tst source (env-declarations env)
- (pt (cadr code) env 'PRED)
- (pt (caddr code) env use)
- (if (length? code 3)
- (new-cst source (env-declarations env) undef-object)
- (pt (cadddr code) env use)))))
-
- (define (pt-cond source env use)
-
- (define (pt-clauses clauses)
- (if (length? clauses 0)
- (new-cst source (env-declarations env) undef-object)
- (let* ((clause* (car clauses))
- (clause (source-code clause*)))
- (cond ((eq? (source-code (car clause)) ELSE-sym)
- (pt-sequence clause* (cdr clause) env use))
- ((length? clause 1)
- (new-disj clause* (env-declarations env)
- (pt (car clause) env (if (eq? use 'TRUE) 'TRUE 'PRED))
- (pt-clauses (cdr clauses))))
- ((eq? (source-code (cadr clause)) =>-sym)
- (new-disj-call clause* (env-declarations env)
- (pt (car clause) env 'TRUE)
- (pt (caddr clause) env 'TRUE)
- (pt-clauses (cdr clauses))))
- (else
- (new-tst clause* (env-declarations env)
- (pt (car clause) env 'PRED)
- (pt-sequence clause* (cdr clause) env use)
- (pt-clauses (cdr clauses))))))))
-
- (pt-clauses (cdr (source-code source))))
-
- (define (pt-and source env use)
-
- (define (pt-exprs exprs)
- (cond ((length? exprs 0)
- (new-cst source (env-declarations env) #t))
- ((length? exprs 1)
- (pt (car exprs) env use))
- (else
- (new-conj (car exprs) (env-declarations env)
- (pt (car exprs) env (if (eq? use 'TRUE) 'TRUE 'PRED))
- (pt-exprs (cdr exprs))))))
-
- (pt-exprs (cdr (source-code source))))
-
- (define (pt-or source env use)
-
- (define (pt-exprs exprs)
- (cond ((length? exprs 0)
- (new-cst source (env-declarations env) false-object))
- ((length? exprs 1)
- (pt (car exprs) env use))
- (else
- (new-disj (car exprs) (env-declarations env)
- (pt (car exprs) env (if (eq? use 'TRUE) 'TRUE 'PRED))
- (pt-exprs (cdr exprs))))))
-
- (pt-exprs (cdr (source-code source))))
-
- (define (pt-case source env use)
- (let ((code (source-code source))
- (temp (new-temps source '(temp))))
-
- (define (pt-clauses clauses)
- (if (length? clauses 0)
- (new-cst source (env-declarations env) undef-object)
- (let* ((clause* (car clauses))
- (clause (source-code clause*)))
- (if (eq? (source-code (car clause)) ELSE-sym)
- (pt-sequence clause* (cdr clause) env use)
- (new-tst clause* (env-declarations env)
- (new-call* clause* (add-not-safe (env-declarations env))
- (new-ref-extended-bindings clause* **CASE-MEMV-sym env)
- (list (new-ref clause* (env-declarations env)
- (car temp))
- (new-cst (car clause) (env-declarations env)
- (source->expression (car clause)))))
- (pt-sequence clause* (cdr clause) env use)
- (pt-clauses (cdr clauses)))))))
-
- (new-call* source (env-declarations env)
- (new-prc source (env-declarations env) #f 1 #f temp
- (pt-clauses (cddr code)))
- (list (pt (cadr code) env 'TRUE)))))
-
- (define (pt-let source env use)
- (let ((code (source-code source)))
- (if (bindable-var? (cadr code) env)
- (let* ((self (new-variables (list (cadr code))))
- (bindings (map source-code (source-code (caddr code))))
- (vars (new-variables (map car bindings)))
- (vals (map (lambda (x) (pt (cadr x) env 'TRUE)) bindings))
- (env (env-frame (env-frame env vars) self))
- (self-proc (list (new-prc source (env-declarations env)
- #f
- (length vars)
- #f
- vars
- (pt-body source (cdddr code) env use)))))
- (set-prc-names! self self-proc)
- (set-prc-names! vars vals)
- (new-call* source (env-declarations env)
- (new-prc source (env-declarations env) #f 1 #f self
- (new-call* source (env-declarations env)
- (new-ref source (env-declarations env) (car self))
- vals))
- self-proc))
- (if (null? (source-code (cadr code)))
- (pt-body source (cddr code) env use)
- (let* ((bindings (map source-code (source-code (cadr code))))
- (vars (new-variables (map car bindings)))
- (vals (map (lambda (x) (pt (cadr x) env 'TRUE)) bindings))
- (env (env-frame env vars)))
- (set-prc-names! vars vals)
- (new-call* source (env-declarations env)
- (new-prc source (env-declarations env)
- #f
- (length vars)
- #f
- vars
- (pt-body source (cddr code) env use))
- vals))))))
-
- (define (pt-let* source env use)
- (let ((code (source-code source)))
-
- (define (pt-bindings bindings env use)
- (if (null? bindings)
- (pt-body source (cddr code) env use)
- (let* ((binding* (car bindings))
- (binding (source-code binding*))
- (vars (new-variables (list (car binding))))
- (vals (list (pt (cadr binding) env 'TRUE)))
- (env (env-frame env vars)))
- (set-prc-names! vars vals)
- (new-call* binding* (env-declarations env)
- (new-prc binding* (env-declarations env) #f 1 #f vars
- (pt-bindings (cdr bindings) env use))
- vals))))
-
- (pt-bindings (source-code (cadr code)) env use)))
-
- (define (pt-letrec source env use)
- (let* ((code (source-code source))
- (bindings (map source-code (source-code (cadr code))))
- (vars* (new-variables (map car bindings)))
- (env* (env-frame env vars*)))
- (pt-recursive-let
- source
- vars*
- (map (lambda (x) (pt (cadr x) env* 'TRUE)) bindings)
- (cddr code)
- env*
- use)))
-
- (define (pt-recursive-let source vars vals body env use)
-
- (define (val-of var)
- (list-ref vals (- (length vars) (length (memq var vars)))))
-
- (define (bind-in-order order)
- (if (null? order)
- (pt-body source body env use)
-
- ; get vars to be bound and vars to be assigned
-
- (let* ((vars-set (car order))
- (vars (set->list vars-set)))
- (let loop1 ((l (reverse vars)) (vars-b '()) (vals-b '()) (vars-a '()))
- (if (not (null? l))
- (let* ((var (car l))
- (val (val-of var)))
- (if (or (prc? val)
- (set-empty?
- (set-intersection (free-variables val) vars-set)))
- (loop1 (cdr l)
- (cons var vars-b)
- (cons val vals-b)
- vars-a)
- (loop1 (cdr l)
- vars-b
- vals-b
- (cons var vars-a))))
-
- (let* ((result1
- (let loop2 ((l vars-a))
- (if (not (null? l))
-
- (let* ((var (car l))
- (val (val-of var)))
- (new-seq source (env-declarations env)
- (new-set source (env-declarations env) var val)
- (loop2 (cdr l))))
-
- (bind-in-order (cdr order)))))
-
- (result2
- (if (null? vars-b)
- result1
- (new-call* source (env-declarations env)
- (new-prc source (env-declarations env) #f (length vars-b) #f vars-b
- result1)
- vals-b)))
-
- (result3
- (if (null? vars-a)
- result2
- (new-call* source (env-declarations env)
- (new-prc source (env-declarations env) #f (length vars-a) #f vars-a
- result2)
- (map (lambda (var)
- (new-cst source (env-declarations env) undef-object))
- vars-a)))))
-
- result3))))))
-
- (set-prc-names! vars vals)
-
- (bind-in-order
- (topological-sort
- (transitive-closure
- (dependency-graph vars vals)))))
-
- (define (pt-begin source env use)
- (pt-sequence source (cdr (source-code source)) env use))
-
- (define (pt-do source env use)
- (let* ((code (source-code source))
- (loop (new-temps source '(loop)))
- (bindings (map source-code (source-code (cadr code))))
- (vars (new-variables (map car bindings)))
- (init (map (lambda (x) (pt (cadr x) env 'TRUE)) bindings))
- (env (env-frame env vars))
- (step (map (lambda (x)
- (pt (if (length? x 2) (car x) (caddr x)) env 'TRUE))
- bindings))
- (exit (source-code (caddr code))))
- (set-prc-names! vars init)
- (new-call* source (env-declarations env)
- (new-prc source (env-declarations env) #f 1 #f loop
- (new-call* source (env-declarations env)
- (new-ref source (env-declarations env) (car loop)) init))
- (list
- (new-prc source (env-declarations env) #f (length vars) #f vars
- (new-tst source (env-declarations env)
- (pt (car exit) env 'PRED)
- (if (length? exit 1)
- (new-cst (caddr code) (env-declarations env) undef-object)
- (pt-sequence (caddr code) (cdr exit) env use))
- (if (length? code 3)
- (new-call* source (env-declarations env)
- (new-ref source (env-declarations env) (car loop))
- step)
- (new-seq source (env-declarations env)
- (pt-sequence source (cdddr code) env 'NONE)
- (new-call* source (env-declarations env)
- (new-ref source (env-declarations env)
- (car loop))
- step)))))))))
-
- (define (pt-combination source env use)
- (let* ((code (source-code source))
- (oper (pt (car code) env 'TRUE))
- (decl (node-decl oper)))
- (new-call* source (env-declarations env)
- oper
- (map (lambda (x) (pt x env 'TRUE)) (cdr code)))))
-
- (define (pt-delay source env use)
- (let ((code (source-code source)))
- (new-fut source (add-delay (env-declarations env))
- (pt (cadr code) env 'TRUE))))
-
- (define (pt-future source env use)
- (let ((decl (env-declarations env))
- (code (source-code source)))
- (if (eq? (futures-method decl) OFF-sym)
- (pt (cadr code) env 'TRUE)
- (new-fut source decl
- (pt (cadr code) env 'TRUE)))))
-
- ; Expression identification predicates and syntax checking.
-
- (define (self-eval-expr? source)
- (let ((code (source-code source)))
- (and (not (pair? code)) (not (symbol-object? code)))))
-
- (define (quote-expr? source)
- (match QUOTE-sym 1 source))
-
- (define (quasiquote-expr? source)
- (match QUASIQUOTE-sym 1 source))
-
- (define (unquote-expr? source)
- (match UNQUOTE-sym 1 source))
-
- (define (unquote-splicing-expr? source)
- (match UNQUOTE-SPLICING-sym 1 source))
-
- (define (var-expr? source env)
- (let ((code (source-code source)))
- (and (symbol-object? code)
- (not-keyword source env code)
- (not-macro source env code))))
-
- (define (not-macro source env name)
- (if (env-lookup-macro env name)
- (pt-syntax-error source "Macro name can't be used as a variable:" name)
- #t))
-
- (define (bindable-var? source env)
- (let ((code (source-code source)))
- (and (symbol-object? code)
- (not-keyword source env code))))
-
- (define (not-keyword source env name)
- (if (or (memq name common-keywords)
- (memq name (dialect-specific-keywords
- (scheme-dialect (env-declarations env)))))
- (pt-syntax-error source "Predefined keyword can't be used as a variable:" name)
- #t))
-
- (define (set!-expr? source env)
- (and (match SET!-sym 2 source)
- (var-expr? (cadr (source-code source)) env)))
-
- (define (lambda-expr? source env)
- (and (match LAMBDA-sym -2 source)
- (proper-parms? (source->parms (cadr (source-code source))) env)))
-
- (define (if-expr? source)
- (and (match IF-sym -2 source)
- (or (<= (length (source-code source)) 4)
- (pt-syntax-error source "Ill-formed special form" IF-sym))))
-
- (define (cond-expr? source)
- (and (match COND-sym -1 source)
- (proper-clauses? source)))
-
- (define (and-expr? source)
- (match AND-sym 0 source))
-
- (define (or-expr? source)
- (match OR-sym 0 source))
-
- (define (case-expr? source)
- (and (match CASE-sym -2 source)
- (proper-case-clauses? source)))
-
- (define (let-expr? source env)
- (and (match LET-sym -2 source)
- (let ((code (source-code source)))
- (if (bindable-var? (cadr code) env)
- (and (proper-bindings? (caddr code) #t env)
- (or (> (length code) 3)
- (pt-syntax-error source "Ill-formed named 'let'")))
- (proper-bindings? (cadr code) #t env)))))
-
- (define (let*-expr? source env)
- (and (match LET*-sym -2 source)
- (proper-bindings? (cadr (source-code source)) #f env)))
-
- (define (letrec-expr? source env)
- (and (match LETREC-sym -2 source)
- (proper-bindings? (cadr (source-code source)) #t env)))
-
- (define (begin-expr? source)
- (match BEGIN-sym -1 source))
-
- (define (do-expr? source env)
- (and (match DO-sym -2 source)
- (proper-do-bindings? source env)
- (proper-do-exit? source)))
-
- (define (define-expr? source env)
- (and (match DEFINE-sym -1 source)
- (proper-definition? source env)
- (let ((v (definition-variable source)))
- (not-macro v env (source-code v)))))
-
- (define (combination-expr? source)
- (let ((length (proper-length (source-code source))))
- (if length
- (or (> length 0)
- (pt-syntax-error source "Ill-formed procedure call"))
- (pt-syntax-error source "Ill-terminated procedure call"))))
-
- (define (delay-expr? source env)
- (and (not (eq? (scheme-dialect (env-declarations env)) IEEE-SCHEME-sym))
- (match DELAY-sym 1 source)))
-
- (define (future-expr? source env)
- (and (eq? (scheme-dialect (env-declarations env)) MULTILISP-sym)
- (match FUTURE-sym 1 source)))
-
- (define (macro-expr? source env)
- (let ((code (source-code source)))
- (and (pair? code)
- (symbol-object? (source-code (car code)))
- (let ((macr (env-lookup-macro env (source-code (car code)))))
- (and macr
- (let ((len (proper-length (cdr code))))
- (if len
- (let ((len* (+ len 1))
- (size (car macr)))
- (or (if (> size 0) (= len* size) (>= len* (- size)))
- (pt-syntax-error source "Ill-formed macro form")))
- (pt-syntax-error source "Ill-terminated macro form"))))))))
-
- (define (define-macro-expr? source env)
- (and (match **DEFINE-MACRO-sym -1 source)
- (proper-definition? source env)))
-
- (define (declare-expr? source)
- (match **DECLARE-sym -1 source))
-
- (define (include-expr? source)
- (match **INCLUDE-sym 1 source))
-
- (define (begin-defs-expr? source)
- (match BEGIN-sym 0 source))
-
- (define (match keyword size source)
- (let ((code (source-code source)))
- (and (pair? code)
- (eq? (source-code (car code)) keyword)
- (let ((length (proper-length (cdr code))))
- (if length
- (or (if (> size 0) (= length size) (>= length (- size)))
- (pt-syntax-error source "Ill-formed special form" keyword))
- (pt-syntax-error source "Ill-terminated special form" keyword))))))
-
- (define (proper-length l)
- (define (length l n)
- (cond ((pair? l) (length (cdr l) (+ n 1)))
- ((null? l) n)
- (else #f)))
- (length l 0))
-
- (define (proper-definition? source env)
- (let* ((code (source-code source))
- (pattern* (cadr code))
- (pattern (source-code pattern*))
- (body (cddr code)))
- (cond ((bindable-var? pattern* env)
- (cond ((length? body 0) #t) ; an unbound variable
- ((length? body 1) #t) ; a bound variable
- (else
- (pt-syntax-error source "Ill-formed definition body"))))
- ((pair? pattern)
- (if (length? body 0)
- (pt-syntax-error
- source
- "Body of a definition must have at least one expression"))
- (if (bindable-var? (car pattern) env)
- (proper-parms? (cdr pattern) env)
- (pt-syntax-error
- (car pattern)
- "Procedure name must be an identifier")))
- (else
- (pt-syntax-error pattern* "Ill-formed definition pattern")))))
-
- (define (definition-variable def)
- (let* ((code (source-code def))
- (pattern (cadr code)))
- (if (pair? (source-code pattern))
- (car (source-code pattern))
- pattern)))
-
- (define (definition-value def)
- (let ((code (source-code def))
- (loc (source-locat def)))
- (cond ((pair? (source-code (cadr code)))
- (make-source
- (cons (make-source LAMBDA-sym loc)
- (cons (parms->source (cdr (source-code (cadr code))) loc)
- (cddr code)))
- loc))
- ((null? (cddr code))
- (make-source
- (list (make-source QUOTE-sym loc) (make-source undef-object loc))
- loc))
- (else
- (caddr code)))))
-
- (define (parms->source parms loc)
- (if (or (pair? parms) (null? parms)) (make-source parms loc) parms))
-
- (define (proper-parms? parms env)
-
- (define (proper-parms parms seen optional-seen)
- (cond ((pair? parms)
- (let* ((parm* (car parms))
- (parm (source-code parm*)))
- (cond ((pair? parm)
- (if (eq? (scheme-dialect (env-declarations env)) MULTILISP-sym)
- (let ((length (proper-length parm)))
- (if (or (eqv? length 1) (eqv? length 2))
- (let ((var (car parm)))
- (if (bindable-var? var env)
- (if (memq (source-code var) seen)
- (pt-syntax-error
- var
- "Duplicate parameter in parameter list")
- (proper-parms
- (cdr parms)
- (cons (source-code var) seen)
- #t))
- (pt-syntax-error
- var
- "Parameter must be an identifier")))
- (pt-syntax-error parm* "Ill-formed optional parameter")))
- (pt-syntax-error
- parm*
- "optional parameters illegal in this dialect")))
- (optional-seen
- (pt-syntax-error parm* "Optional parameter expected"))
- ((bindable-var? parm* env)
- (if (memq parm seen)
- (pt-syntax-error
- parm*
- "Duplicate parameter in parameter list"))
- (proper-parms
- (cdr parms)
- (cons parm seen)
- #f))
- (else
- (pt-syntax-error parm* "Parameter must be an identifier")))))
- ((null? parms)
- #t)
- ((bindable-var? parms env)
- (if (memq (source-code parms) seen)
- (pt-syntax-error parms "Duplicate parameter in parameter list")
- #t))
- (else
- (pt-syntax-error parms "Rest parameter must be an identifier"))))
-
- (proper-parms parms '() #f))
-
- (define (proper-clauses? source)
-
- (define (proper-clauses clauses)
- (or (null? clauses)
- (let* ((clause* (car clauses))
- (clause (source-code clause*))
- (length (proper-length clause)))
- (if length
- (if (>= length 1)
- (if (eq? (source-code (car clause)) ELSE-sym)
- (cond ((= length 1)
- (pt-syntax-error
- clause*
- "Else clause must have a body"))
- ((not (null? (cdr clauses)))
- (pt-syntax-error
- clause*
- "Else clause must be the last clause"))
- (else
- (proper-clauses (cdr clauses))))
- (if (and (>= length 2)
- (eq? (source-code (cadr clause)) =>-sym)
- (not (= length 3)))
- (pt-syntax-error
- (cadr clause)
- "'=>' must be followed by a single expression")
- (proper-clauses (cdr clauses))))
- (pt-syntax-error clause* "Ill-formed 'cond' clause"))
- (pt-syntax-error clause* "Ill-terminated 'cond' clause")))))
-
- (proper-clauses (cdr (source-code source))))
-
- (define (proper-case-clauses? source)
-
- (define (proper-case-clauses clauses)
- (or (null? clauses)
- (let* ((clause* (car clauses))
- (clause (source-code clause*))
- (length (proper-length clause)))
- (if length
- (if (>= length 2)
- (if (eq? (source-code (car clause)) ELSE-sym)
- (if (not (null? (cdr clauses)))
- (pt-syntax-error
- clause*
- "Else clause must be the last clause")
- (proper-case-clauses (cdr clauses)))
- (begin
- (proper-selector-list? (car clause))
- (proper-case-clauses (cdr clauses))))
- (pt-syntax-error
- clause*
- "A 'case' clause must have a selector list and a body"))
- (pt-syntax-error clause* "Ill-terminated 'case' clause")))))
-
- (proper-case-clauses (cddr (source-code source))))
-
- (define (proper-selector-list? source)
- (let* ((code (source-code source))
- (length (proper-length code)))
- (if length
- (or (>= length 1)
- (pt-syntax-error
- source
- "Selector list must contain at least one element"))
- (pt-syntax-error source "Ill-terminated selector list"))))
-
- (define (proper-bindings? bindings check-dupl? env)
-
- (define (proper-bindings l seen)
- (cond ((pair? l)
- (let* ((binding* (car l))
- (binding (source-code binding*)))
- (if (eqv? (proper-length binding) 2)
- (let ((var (car binding)))
- (if (bindable-var? var env)
- (if (and check-dupl? (memq (source-code var) seen))
- (pt-syntax-error var "Duplicate variable in bindings")
- (proper-bindings (cdr l)
- (cons (source-code var) seen)))
- (pt-syntax-error
- var
- "Binding variable must be an identifier")))
- (pt-syntax-error binding* "Ill-formed binding"))))
- ((null? l)
- #t)
- (else
- (pt-syntax-error bindings "Ill-terminated binding list"))))
-
- (proper-bindings (source-code bindings) '()))
-
- (define (proper-do-bindings? source env)
- (let ((bindings (cadr (source-code source))))
-
- (define (proper-bindings l seen)
- (cond ((pair? l)
- (let* ((binding* (car l))
- (binding (source-code binding*))
- (length (proper-length binding)))
- (if (or (eqv? length 2) (eqv? length 3))
- (let ((var (car binding)))
- (if (bindable-var? var env)
- (if (memq (source-code var) seen)
- (pt-syntax-error var "Duplicate variable in bindings")
- (proper-bindings (cdr l)
- (cons (source-code var) seen)))
- (pt-syntax-error
- var
- "Binding variable must be an identifier")))
- (pt-syntax-error binding* "Ill-formed binding"))))
- ((null? l)
- #t)
- (else
- (pt-syntax-error bindings "Ill-terminated binding list"))))
-
- (proper-bindings (source-code bindings) '())))
-
- (define (proper-do-exit? source)
- (let* ((code (source-code (caddr (source-code source))))
- (length (proper-length code)))
- (if length
- (or (> length 0)
- (pt-syntax-error source "Ill-formed exit clause"))
- (pt-syntax-error source "Ill-terminated exit clause"))))
-
- (define (include-filename source)
- (source-code (cadr (source-code source))))
-
- (define (begin-defs-body source)
- (cdr (source-code source)))
-
- (define (length? l n)
- (cond ((null? l) (= n 0))
- ((> n 0) (length? (cdr l) (- n 1)))
- (else #f)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Variable dependency analysis for recursive definitions (e.g. 'letrec's).
-
- (define (make-gnode label edges)
- (vector gnode-tag label edges))
-
- (define (gnode? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) gnode-tag)))
-
- (define (gnode-label x) (vector-ref x 1))
- (define (gnode-edges x) (vector-ref x 2))
- (define (gnode-label-set! x y) (vector-set! x 1 y))
- (define (gnode-edges-set! x y) (vector-set! x 2 y))
-
- (define gnode-tag (list 'gnode))
-
- (define (dependency-graph vars vals)
- (define (dgraph vars* vals*)
- (if (null? vars*)
- (set-empty)
- (let ((var (car vars*)) (val (car vals*)))
- (set-adjoin (dgraph (cdr vars*) (cdr vals*))
- (make-gnode var (set-intersection
- (list->set vars)
- (free-variables val)))))))
- (dgraph vars vals))
-
- (define (transitive-closure graph)
- (define changed? #f)
- (define (closure edges)
- (list->set (set-union edges
- (apply set-union
- (map (lambda (label)
- (gnode-edges (gnode-find label graph)))
- (set->list edges))))))
- (let ((new-graph
- (set-map (lambda (x)
- (let ((new-edges (closure (gnode-edges x))))
- (if (not (set-equal? new-edges (gnode-edges x)))
- (set! changed? #t))
- (make-gnode (gnode-label x) new-edges)))
- graph)))
- (if changed? (transitive-closure new-graph) new-graph)))
-
- (define (gnode-find label graph)
- (define (find label l)
- (cond ((null? l) #f)
- ((eq? (gnode-label (car l)) label) (car l))
- (else (find label (cdr l)))))
- (find label (set->list graph)))
-
- (define (topological-sort graph) ; topological sort fixed to handle cycles
- (if (set-empty? graph)
- '()
- (let ((to-remove (or (remove-no-edges graph) (remove-cycle graph))))
- (let ((labels (set-map gnode-label to-remove)))
- (cons labels
- (topological-sort
- (set-map (lambda (x)
- (make-gnode
- (gnode-label x)
- (set-difference (gnode-edges x) labels)))
- (set-difference graph to-remove))))))))
-
- (define (remove-no-edges graph)
- (let ((nodes-with-no-edges
- (set-keep (lambda (x) (set-empty? (gnode-edges x))) graph)))
- (if (set-empty? nodes-with-no-edges)
- #f
- nodes-with-no-edges)))
-
- (define (remove-cycle graph)
- (define (remove l)
- (let ((edges (gnode-edges (car l))))
- (define (equal-edges? x) (set-equal? (gnode-edges x) edges))
- (define (member-edges? x) (set-member? (gnode-label x) edges))
- (if (set-member? (gnode-label (car l)) edges)
- (let ((edge-graph (set-keep member-edges? graph)))
- (if (set-every? equal-edges? edge-graph)
- edge-graph
- (remove (cdr l))))
- (remove (cdr l)))))
- (remove (set->list graph)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Declaration handling:
- ; --------------------
-
- ; A declaration has the form: (##declare <item1> <item2> ...)
- ;
- ; an <item> can be one of 6 types:
- ;
- ; - flag declaration : (<id>)
- ; - parameterized declaration : (<id> <parameter>)
- ; - boolean declaration : (<id>) or (NOT <id>)
- ; - namable declaration : (<id> <name>...)
- ; - namable boolean declaration: (<id> <name>...) or (NOT <id> <name>...)
- ; - namable string declaration : (<id> <string> <name>...)
-
- (define (transform-declaration source)
- (let ((code (source-code source)))
- (if (not (pair? code))
- (pt-syntax-error source "Ill-formed declaration")
- (let* ((pos (not (eq? (source-code (car code)) NOT-sym)))
- (x (if pos code (cdr code))))
- (if (not (pair? x))
- (pt-syntax-error source "Ill-formed declaration")
- (let* ((id* (car x))
- (id (source-code id*)))
-
- (cond ((not (symbol-object? id))
- (pt-syntax-error id* "Declaration name must be an identifier"))
-
- ((assq id flag-declarations)
- (cond ((not pos)
- (pt-syntax-error id* "Declaration can't be negated"))
- ((null? (cdr x))
- (flag-decl
- source
- (cdr (assq id flag-declarations))
- id))
- (else
- (pt-syntax-error source "Ill-formed declaration"))))
-
- ((memq id parameterized-declarations)
- (cond ((not pos)
- (pt-syntax-error id* "Declaration can't be negated"))
- ((eqv? (proper-length x) 2)
- (parameterized-decl
- source
- id
- (source->expression (cadr x))))
- (else
- (pt-syntax-error source "Ill-formed declaration"))))
-
- ((memq id boolean-declarations)
- (if (null? (cdr x))
- (boolean-decl source id pos)
- (pt-syntax-error source "Ill-formed declaration")))
-
- ((assq id namable-declarations)
- (cond ((not pos)
- (pt-syntax-error id* "Declaration can't be negated"))
- (else
- (namable-decl
- source
- (cdr (assq id namable-declarations))
- id
- (map source->expression (cdr x))))))
-
- ((memq id namable-boolean-declarations)
- (namable-boolean-decl
- source
- id
- pos
- (map source->expression (cdr x))))
-
- ((memq id namable-string-declarations)
- (if (not (pair? (cdr x)))
- (pt-syntax-error source "Ill-formed declaration")
- (let* ((str* (cadr x))
- (str (source-code str*)))
- (cond ((not pos)
- (pt-syntax-error id* "Declaration can't be negated"))
- ((not (string? str))
- (pt-syntax-error str* "String expected"))
- (else
- (namable-string-decl
- source
- id
- str
- (map source->expression (cddr x))))))))
-
- (else
- (pt-syntax-error id* "Unknown declaration")))))))))
-
- (define (add-declarations source env)
- (let loop ((l (cdr (source-code source))) (env env))
- (if (pair? l)
- (loop (cdr l) (env-declare env (transform-declaration (car l))))
- env)))
-
- (define (add-decl d decl)
- (env-declare decl d))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Macro handling:
- ; --------------
-
- (define (add-macro source env)
-
- (define (form-size parms)
- (let loop ((l parms) (n 1))
- (if (pair? l)
- (loop (cdr l) (+ n 1))
- (if (null? l) n (- n)))))
-
- (define (error-proc . msgs)
- (apply compiler-user-error
- (cons (source-locat source)
- (cons "(in macro body)" msgs))))
-
- (let ((var (definition-variable source))
- (proc (definition-value source)))
- (if (lambda-expr? proc env)
- (env-macro env
- (source-code var)
- (cons (form-size (source->parms (cadr (source-code proc))))
- (scheme-global-eval (source->expression proc)
- error-proc)))
- (pt-syntax-error source "Macro value must be a lambda expression"))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (ptree.begin! info-port) ; initialize package
- (set! *ptree-port* info-port)
- '())
-
- (define (ptree.end!) ; finalize package
- '())
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Stuff local to the package:
-
- (define *ptree-port* '())
-
- ;==============================================================================
-